1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import com.google.common.collect.testing.Helpers.NullsBeforeTwo;
20  import com.google.common.collect.testing.SafeTreeMap;
21  import com.google.common.collect.testing.SortedMapTestSuiteBuilder;
22  import com.google.common.collect.testing.TestStringSortedMapGenerator;
23  import com.google.common.collect.testing.features.CollectionFeature;
24  import com.google.common.collect.testing.features.CollectionSize;
25  import com.google.common.collect.testing.features.MapFeature;
26  
27  import junit.framework.Test;
28  import junit.framework.TestSuite;
29  
30  import java.util.Collection;
31  import java.util.Comparator;
32  import java.util.Iterator;
33  import java.util.Map;
34  import java.util.Map.Entry;
35  import java.util.Set;
36  import java.util.SortedMap;
37  
38  /**
39   * Tests for {@code ForwardingSortedMap}.
40   *
41   * @author Robert Konigsberg
42   */
43  public class ForwardingSortedMapTest extends ForwardingMapTest {
44    static class StandardImplForwardingSortedMap<K, V>
45        extends ForwardingSortedMap<K, V> {
46      private final SortedMap<K, V> backingMap;
47  
48      StandardImplForwardingSortedMap(SortedMap<K, V> backingMap) {
49        this.backingMap = backingMap;
50      }
51  
52      @Override protected SortedMap<K, V> delegate() {
53        return backingMap;
54      }
55  
56      @Override public boolean containsKey(Object key) {
57        return standardContainsKey(key);
58      }
59  
60      @Override public boolean containsValue(Object value) {
61        return standardContainsValue(value);
62      }
63  
64      @Override public void putAll(Map<? extends K, ? extends V> map) {
65        standardPutAll(map);
66      }
67  
68      @Override public V remove(Object object) {
69        return standardRemove(object);
70      }
71  
72      @Override public boolean equals(Object object) {
73        return standardEquals(object);
74      }
75  
76      @Override public int hashCode() {
77        return standardHashCode();
78      }
79  
80      @Override public Set<K> keySet() {
81        return new StandardKeySet();
82      }
83  
84      @Override public Collection<V> values() {
85        return new StandardValues();
86      }
87  
88      @Override public String toString() {
89        return standardToString();
90      }
91  
92      @Override public Set<Entry<K, V>> entrySet() {
93        return new StandardEntrySet() {
94          @Override
95          public Iterator<Entry<K, V>> iterator() {
96            return backingMap.entrySet().iterator();
97          }
98        };
99      }
100 
101     @Override public void clear() {
102       standardClear();
103     }
104 
105     @Override public boolean isEmpty() {
106       return standardIsEmpty();
107     }
108 
109     @Override public SortedMap<K, V> subMap(K fromKey, K toKey) {
110       return standardSubMap(fromKey, toKey);
111     }
112   }
113 
114   public static Test suite() {
115     TestSuite suite = new TestSuite();
116 
117     suite.addTestSuite(ForwardingSortedMapTest.class);
118     suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
119       @Override protected SortedMap<String, String> create(
120           Entry<String, String>[] entries) {
121         SortedMap<String, String> map = new SafeTreeMap<String, String>();
122         for (Entry<String, String> entry : entries) {
123           map.put(entry.getKey(), entry.getValue());
124         }
125         return new StandardImplForwardingSortedMap<String, String>(map);
126       }
127     }).named("ForwardingSortedMap[SafeTreeMap] with no comparator and standard "
128         + "implementations").withFeatures(CollectionSize.ANY,
129         CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES,
130         MapFeature.GENERAL_PURPOSE, CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
131         .createTestSuite());
132     suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
133       private final Comparator<String> comparator = NullsBeforeTwo.INSTANCE;
134 
135       @Override protected SortedMap<String, String> create(
136           Entry<String, String>[] entries) {
137         SortedMap<String, String> map =
138             new SafeTreeMap<String, String>(comparator);
139         for (Entry<String, String> entry : entries) {
140           map.put(entry.getKey(), entry.getValue());
141         }
142         return new StandardImplForwardingSortedMap<String, String>(map);
143       }
144     }).named("ForwardingSortedMap[SafeTreeMap] with natural comparator and "
145         + "standard implementations").withFeatures(CollectionSize.ANY,
146         CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES,
147         MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_ANY_NULL_QUERIES,
148         MapFeature.GENERAL_PURPOSE,
149         CollectionFeature.SUPPORTS_ITERATOR_REMOVE).createTestSuite());
150     suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
151       @Override protected SortedMap<String, String> create(
152           Entry<String, String>[] entries) {
153         ImmutableSortedMap.Builder<String, String> builder =
154             ImmutableSortedMap.naturalOrder();
155         for (Entry<String, String> entry : entries) {
156           builder.put(entry.getKey(), entry.getValue());
157         }
158         return new StandardImplForwardingSortedMap<String, String>(
159             builder.build());
160       }
161     }).named("ForwardingSortedMap[ImmutableSortedMap] with standard "
162         + "implementations").withFeatures(
163         CollectionSize.ANY, MapFeature.REJECTS_DUPLICATES_AT_CREATION,
164         MapFeature.ALLOWS_ANY_NULL_QUERIES)
165         .createTestSuite());
166 
167     return suite;
168   }
169 
170   @Override public void setUp() throws Exception {
171     super.setUp();
172     /*
173      * Class parameters must be raw, so we can't create a proxy with generic
174      * type arguments. The created proxy only records calls and returns null, so
175      * the type is irrelevant at runtime.
176      */
177     @SuppressWarnings("unchecked")
178     final SortedMap<String, Boolean> sortedMap =
179         createProxyInstance(SortedMap.class);
180     forward = new ForwardingSortedMap<String, Boolean>() {
181       @Override protected SortedMap<String, Boolean> delegate() {
182         return sortedMap;
183       }
184     };
185   }
186 
187   public void testComparator() {
188     forward().comparator();
189     assertEquals("[comparator]", getCalls());
190   }
191 
192   public void testFirstKey() {
193     forward().firstKey();
194     assertEquals("[firstKey]", getCalls());
195   }
196 
197   public void testHeadMap_K() {
198     forward().headMap("asdf");
199     assertEquals("[headMap(Object)]", getCalls());
200   }
201 
202   public void testLastKey() {
203     forward().lastKey();
204     assertEquals("[lastKey]", getCalls());
205   }
206 
207   public void testSubMap_K_K() {
208     forward().subMap("first", "last");
209     assertEquals("[subMap(Object,Object)]", getCalls());
210   }
211 
212   public void testTailMap_K() {
213     forward().tailMap("last");
214     assertEquals("[tailMap(Object)]", getCalls());
215   }
216 
217   @Override SortedMap<String, Boolean> forward() {
218     return (SortedMap<String, Boolean>) super.forward();
219   }
220 }